#ifndef INTERFACE_H
#define INTERFACE_H
#include <cstdint>

/**
 * @brief 开环控制系统
 */
template <typename InputType, typename OutputType>
class OpenLoopController {
public:
    virtual ~OpenLoopController() = default;

    virtual void setReference(InputType const& ref) = 0;
    virtual OutputType calculate() = 0;
    virtual OutputType getOutput() const = 0;
    virtual void reset() = 0;
};
/**
 * @brief 闭环控制系统
 */
template <typename InputType, typename OutputType>
class CloseLoopController {
public:
    virtual ~CloseLoopController() = default;

    virtual void setReference(InputType const& ref) = 0;
    virtual void setFeedback(InputType const& fdb) = 0;
    virtual OutputType calculate() = 0;
    virtual OutputType getOutput() const = 0;
    virtual void reset() = 0;
};

/**
 * @brief 通用环形缓冲区
 */
template <typename PacketType, size_t bufferSize>
class RingBuffer {
    static_assert(bufferSize > 0, "Buffer size must be at least 1");

    std::array<PacketType, bufferSize> buffer_;
    size_t latest_idx_{bufferSize};  // 最新数据索引（初始无效）
    size_t last_idx_{0};             // 上一次数据索引

public:
    // 获取当前写入位置
    PacketType& getWriteSlot() { return buffer_[next_position()]; }

    // 提交写入
    void commitWrite() {
        latest_idx_ = next_position();
        last_idx_ = latest_idx_;
    }

    // 获取最新有效数据包
    PacketType const& getData() const {
        if (latest_idx_ >= bufferSize) return buffer_[0];  // 初始状态返回首元素
        return buffer_[latest_idx_];
    }

    // 获取上一次数据包
    PacketType const& getPreviousData() const {
        static_assert(bufferSize > 1, "Buffer size must be at least 2 to access previous data");
        return buffer_[last_idx_];
    }

private:
    // 计算下一个写入位置
    [[nodiscard]] size_t next_position() const {
        if (latest_idx_ >= bufferSize) return 0;  // 初始状态使用0索引
        return latest_idx_ + 1 >= bufferSize ? 0 : latest_idx_ + 1;
    }
};

/**
 * @brief 通信接收器接口
 *
 * 定义数据解码规范
 */
template <typename PacketType>
class ReceiverBase {
public:
    virtual ~ReceiverBase() = default;
    virtual void Receive(uint8_t const* data) = 0;
    virtual PacketType const& getData() = 0;
};

template <typename PacketType>
class TransmitterBase {
public:
    virtual ~TransmitterBase() = default;
    virtual void Transmit() = 0;
    virtual void setData(PacketType const&) = 0;
};

#endif  // INTERFACE_H